package com.sy.simpleegg.ui.dialog

import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.Gravity
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import android.widget.TextView.OnEditorActionListener
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.bumptech.glide.Glide
import com.sy.simpleegg.R
import com.sy.simpleegg.adapter.WithdrawalGoodAdapter
import com.sy.simpleegg.bean.WithdrawalGoodBean
import com.sy.simpleegg.config.Config
import com.sy.simpleegg.constant.ProductType
import com.sy.simpleegg.databinding.DialogLocalWithdrawalBinding
import com.sy.simpleegg.ext.countDown
import com.sy.simpleegg.ext.logFile
import com.sy.simpleegg.ext.onClick
import com.sy.simpleegg.ext.showToastMsg
import com.sy.simpleegg.util.QRCodeUtil
import com.sy.simpleegg.util.SoftInputUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch


class LocalWithdrawalDialog(
    private val title: String?,
    private val tips: String,
    private val countDownTime: Int,
    private val withdrawalGoods: MutableList<WithdrawalGoodBean>,
    private var listener: WithdrawalListener,
): DialogFragment(), OnEditorActionListener{

    private lateinit var binding: DialogLocalWithdrawalBinding

    var timeDownScope: CoroutineScope? = null

    private var currentQuantity = 0

    private var uid = ""
    private var uBalanceCoins = 0L
    private var uBalanceBead = 0L

    private var placeOrder = 0//0-未下单 1-下单中 2-下单结束

    override fun onStart() {
        super.onStart()
//        dialog!!.window!!.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)

        val width = resources.getDimensionPixelSize(R.dimen.dialog_withdrawal_width)
        val height = resources.getDimensionPixelSize(R.dimen.dialog_withdrawal_height)
//        val marginBottom = resources.getDimensionPixelSize(R.dimen.dialog_good_detail_margin_bottom)

//        dialog!!.window!!.setLayout(width, height + marginBottom)
        dialog!!.window!!.setLayout(width, height)
        dialog!!.window!!.setGravity(Gravity.CENTER)
        dialog!!.setCanceledOnTouchOutside(false)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View? {
        binding = DialogLocalWithdrawalBinding.inflate(inflater, container, false)
//        setStyle(STYLE_NO_TITLE, R.style.MyDialog)
//        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT))
//        dialog!!.window!!.setGravity(Gravity.BOTTOM)
        dialog!!.window!!.setBackgroundDrawableResource(R.color.transparent)
//        var wlp = dialog!!.window!!.attributes
//        wlp.gravity = Gravity.BOTTOM
//        wlp.width = WindowManager.LayoutParams.MATCH_PARENT
//        wlp.height = WindowManager.LayoutParams.MATCH_PARENT
//        dialog!!.window!!.attributes = wlp

        return binding.root
    }

    @SuppressLint("SetTextI18n")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        try {
            binding.tvTitle.text = title
            binding.tvTips.text = tips
            binding.layoutClose.tvDismiss.text = "${countDownTime}S"

            binding.layoutClose.tvClose.onClick {
//                listener.finish(currentMoney, currentCoins)
                dismissAllowingStateLoss()
            }
            binding.btnFinish.onClick {
                if (checkQuantity(currentQuantity)) {
                    //账户余额充足，可以下单
                    setShowType(2)
                    binding.btnFinish.visibility = View.GONE
                    listener.finish(uid, currentQuantity)
                }else {
//                    dismissAllowingStateLoss()
                }
            }

            binding.etQuantity.addTextChangedListener(object : TextWatcher {
                override fun beforeTextChanged(
                    s: CharSequence?,
                    start: Int,
                    count: Int,
                    after: Int
                ) {

                }

                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                    logFile("onTextChanged s=$s start=$start before=$before count=$count")
                    s?.let {
                        var quantity = 0
                        try {
                            quantity = if (it.isNotEmpty()) it.toString().toInt() else 0
                            if (quantity < 0) {
                                quantity = 0
                                showToastMsg(getString(R.string.withdrawal_quantity_err))
                            }
                        }catch (e: Exception){
                            e.printStackTrace()
                        }

                        checkQuantity(quantity, false)
                    }
                }

                override fun afterTextChanged(s: Editable?) {

                }
            })
            binding.etQuantity.setOnEditorActionListener(OnEditorActionListener { v, actionId, event ->
                logFile("回车 ${EditorInfo.IME_ACTION_DONE} actionId=$actionId")
                if (actionId == EditorInfo.IME_ACTION_DONE){
                    SoftInputUtil.hideSoftInput(binding.root)
                    true
                }
                else if (actionId == EditorInfo.IME_ACTION_NEXT){
                    SoftInputUtil.hideSoftInput(binding.root)
                    true
                }else {
                    false
                }
            })

            binding.rvQuantity.layoutManager = GridLayoutManager(requireContext(), 3)
            binding.rvQuantity.adapter = WithdrawalGoodAdapter(requireContext(), withdrawalGoods, object : WithdrawalGoodAdapter.ItemListener{
                override fun onClick(quantity: Int) {
                    checkQuantity(quantity)
                }
            })

            setShowType(0)
        }catch (e: Exception){
            e.printStackTrace()
            logFile("初始化页面异常：${e.message}")
        }
    }

    override fun showNow(manager: FragmentManager, tag: String?) {
        super.showNow(manager, tag)
        startCountDown(countDownTime)
    }

    override fun show(manager: FragmentManager, tag: String?) {
        super.show(manager, tag)
        startCountDown(countDownTime)
    }

    override fun show(transaction: FragmentTransaction, tag: String?): Int {
        val result = super.show(transaction, tag)
        startCountDown(countDownTime)
        return result
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        listener.dismiss()
    }

    private fun setShowType(type: Int, msg: String = ""){
        lifecycleScope.launch(Dispatchers.Main) {
            when (type){
                0 -> qrCodePage()
                1 -> withdrawalPage()
                2 -> waitingPage()
                3 -> errPage(msg)
            }
        }
    }

    private fun qrCodePage(){
        binding.rlQrcode.visibility = View.VISIBLE
        binding.rlWithdrawal.visibility = View.GONE
        binding.rlWaiting.visibility = View.GONE
        binding.pbQrCode.visibility = View.VISIBLE
        binding.ivQrCode.visibility = View.GONE
    }

    private fun withdrawalPage(){
        binding.rlQrcode.visibility = View.GONE
        binding.rlWithdrawal.visibility = View.VISIBLE
        binding.rlWaiting.visibility = View.GONE
    }

    private fun waitingPage(){
        binding.rlQrcode.visibility = View.GONE
        binding.rlWithdrawal.visibility = View.GONE
        binding.rlWaiting.visibility = View.VISIBLE

        Glide.with(binding.root)
            .load(R.mipmap.ic_paying)
            .fitCenter()
            .into(binding.ivStatus)

        binding.tvMsg.text = "提币中，请稍等"
    }

    private fun errPage(errMsg: String){
        binding.rlQrcode.visibility = View.GONE
        binding.rlWithdrawal.visibility = View.GONE
        binding.rlWaiting.visibility = View.VISIBLE

        Glide.with(binding.root)
            .load(R.mipmap.ic_pay_failed)
            .fitCenter()
            .into(binding.ivStatus)

        binding.tvMsg.text = errMsg
    }

    /**
     * 刷新二维码
     * @param qrCode 二维码数据
     */
    fun refreshQrCode(qrCode: String){
        try {
            if (qrCode.isEmpty()){
                binding.pbQrCode.visibility = View.VISIBLE
                binding.ivQrCode.visibility = View.GONE
                return
            }
            binding.pbQrCode.visibility = View.GONE
            Glide.with(binding.root)
                .load(QRCodeUtil.createQRCode(qrCode, 500, 500))
                .fitCenter()
                .into(binding.ivQrCode)
            binding.ivQrCode.visibility = View.VISIBLE
            startCountDown(countDownTime)
        }catch (e: Exception){
            e.printStackTrace()
            logFile("刷新二维码异常：${e.message}")
        }
    }

    /**
     * 登录成功
     */
    fun loginSuccess(userId: String, balanceCoins: Long, balanceBead: Long){
        uid = userId
        uBalanceCoins = balanceCoins
        uBalanceBead = balanceBead
        setShowType(1)
    }

    fun placeOrder(success: Boolean, errMsg: String?, memberId: String?, balance: Long?){
        if (success){
            if (memberId == uid){
                //出币
                listener.out(uid, currentQuantity)
            }else{
                logFile("用户id不一致，无法出币：uid = $uid memberId=$memberId")
            }
            lifecycleScope.launch {
                delay(500)
                dismissAllowingStateLoss()
            }
        }else{
            setShowType(3, errMsg?:"")
            startCountDown(5)
        }
    }

    @SuppressLint("SetTextI18n")
    private fun startCountDown(timeout: Int){
//        var timeDownScope: CoroutineScope? = null
        timeDownScope?.cancel()

        countDown(
            time = timeout,
            start = {
                timeDownScope = it
                logFile("开始倒计时")
            },
            end = {
                logFile("结束倒计时")
            },
            next = {
                binding.layoutClose.tvDismiss.text = "${it}S"
                if (it == 0){
                    dismissAllowingStateLoss()
                }
            })
    }

    interface WithdrawalListener{
        fun dismiss()

        fun finish(uid: String, withdrawalQuantity: Int)

        fun out(uid: String, withdrawalQuantity: Int)
    }

    fun dpToPx(context: Context, dp: Int): Int {
        val density = context.resources.displayMetrics.density
        return Math.round(dp * density)
    }

    private fun checkQuantity(quantity: Int, canChangeEdit: Boolean = true): Boolean{
        return try {
            startCountDown(countDownTime)
            when (Config.PRODUCT_TYPE){
                ProductType.CURRENCY -> {
                    if (quantity > uBalanceCoins){
                        if (uid.isNotEmpty()) {
                            showToastMsg(getString(R.string.account_out_of_coins))
                        }
                        false
                    }else{
                        currentQuantity = quantity
                        if (canChangeEdit) binding.etQuantity.setText("$currentQuantity")
                        true
                    }
                }
                ProductType.BEAD -> {
                    if (quantity > uBalanceBead){
                        if (uid.isNotEmpty()) {
                            showToastMsg(getString(R.string.account_out_of_bead))
                        }
                        false
                    }else{
                        currentQuantity = quantity
                        if (canChangeEdit) binding.etQuantity.setText("$currentQuantity")
                        true
                    }
                }
            }
        }catch (e: Exception){
            e.printStackTrace()
            logFile("校验提取数量异常：${e.message}")
            false
        }
    }

    override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
        logFile("回车 ${EditorInfo.IME_ACTION_DONE} actionId=$actionId")
        return actionId != EditorInfo.IME_ACTION_DONE
    }
}